home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 3 / CD ACTUAL 3.iso / linux / sonido / mod-0.000 / mod-0 / mod / load.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-10  |  9.9 KB  |  450 lines

  1. /*
  2.  *  load.c - Handles uncompressing and calls loaders for different formats.
  3.  *
  4.  *  (C) 1994 Mikael Nordqvist (d91mn@efd.lth.se, mech@df.lth.se)
  5.  */
  6.  
  7. #include <stdio.h>
  8. #include <unistd.h>
  9. #include <stdlib.h>
  10. #include <sys/types.h>
  11. #include <sys/stat.h>
  12. #include <fcntl.h>
  13. #include <sys/soundcard.h>
  14. #include <sys/ultrasound.h>
  15. #include <limits.h>
  16. #include <string.h>
  17. #include <ctype.h>
  18. #include <assert.h>
  19.  
  20. #include "mod.h"
  21.  
  22. /* External global variables */
  23.  
  24. SEQ_DECLAREBUF();
  25. extern int seqfd, gus_dev;
  26.  
  27. extern struct mod_info M;
  28. extern struct options opt;
  29.  
  30. extern int periodtable[NR_OCTAVES*12];
  31. extern char effect_used[NR_EFX], *effectnames[NR_EFX], workdir[PATH_MAX+1];
  32.  
  33. /* Constants */
  34.  
  35. #define COMPRESSED_GZIP 1
  36. #define COMPRESSED_LHA  2
  37. #define COMPRESSED_ZIP  3
  38. #define COMPRESSED_ARJ  4
  39.  
  40. /* Loads a module and returns nonzero if M is valid after loading
  41.  * Directory may or may not be equal to workdir upon exit.
  42.  */
  43.  
  44. int load_module(void)
  45. {
  46.     int fd, i, tmp, suffix, filetype;
  47.     char buf[PATH_MAX+1]; /* Should actually be a little long but... */
  48.     
  49.     suffix=filetype=0;
  50.     
  51.     /* Set M.filename to modname w/o path */
  52.     tmp=strlen(M.real_filename);
  53.     for(i=tmp-1; i >= 0 && M.real_filename[i] != '/'; )
  54.     --i;
  55.     
  56.     strcpy(M.filename, &M.real_filename[++i]);
  57.     tmp=strlen(M.filename);
  58.     
  59.     if(tmp > 2) {
  60.     if(!strcmp(M.filename+tmp-2, ".z") ||
  61.        !strcmp(M.filename+tmp-2, ".Z")) {
  62.         filetype=COMPRESSED_GZIP;
  63.         suffix=2;
  64.     }
  65.     }
  66.     if(tmp > 3) {
  67.     if(!strcmp(M.filename+tmp-3, ".gz")) {
  68.         filetype=COMPRESSED_GZIP;
  69.         suffix=3;
  70.     }
  71.     }
  72.     if(tmp > 4) {
  73.     if(!strcmp(M.filename+tmp-4, ".lha") ||
  74.        !strcmp(M.filename+tmp-4, ".lzh")) {
  75.         filetype=COMPRESSED_LHA;
  76.         suffix=4;
  77.     }
  78.     else if(!strcmp(M.filename+tmp-4, ".zip")) {
  79.         filetype=COMPRESSED_ZIP;
  80.         suffix=4;
  81.     }
  82.     else if(!strcmp(M.filename+tmp-4, ".arj")) {
  83.         filetype=COMPRESSED_ARJ;
  84.         suffix=4;
  85.     }
  86.     }
  87.     
  88.     M.filename[tmp-suffix]=0; /* Remove suffix */
  89.     
  90.     /* Make sure the file exists by opening and closing the file */
  91.     if(!(fd=open(M.real_filename, O_RDONLY, 0))) {
  92.     print_status("File does not exist");
  93.     info("Unable to open file '%s'.\n", M.real_filename);
  94.     sleep(1);
  95.     return 0;
  96.     }
  97.     close(fd);
  98.  
  99.     /* Print status if we are uncompressing */
  100.     switch(filetype) {
  101.       case COMPRESSED_GZIP:
  102.       case COMPRESSED_LHA:
  103.       case COMPRESSED_ZIP:
  104.       case COMPRESSED_ARJ:
  105.     print_status("Uncompressing module");
  106.     info("Uncompressing module... ");
  107.     break;
  108.       default:
  109.     }
  110.  
  111.     /* Prepare uncompress command */
  112.     switch(filetype) {
  113.       case COMPRESSED_GZIP:
  114.     sprintf(buf, GZIP_COMMAND "%s > " TMP_DIR "/%s 2>/dev/null "
  115.         "< /dev/null",
  116.         escape_name(M.real_filename, 0), escape_name(M.filename, 1));
  117.     break;
  118.       case COMPRESSED_LHA:
  119.     guess_lha_filename();
  120.     chdir(TMP_DIR);
  121.     sprintf(buf, LHA_COMMAND "%s/%s %s >& /dev/null < /dev/null",
  122.         workdir, escape_name(M.real_filename, 0),
  123.         escape_name(M.filename, 1));
  124.     break;
  125.       case COMPRESSED_ZIP:
  126.     guess_zip_filename();
  127.     chdir(TMP_DIR);
  128.     sprintf(buf, ZIP_COMMAND "%s/%s %s >& /dev/null < /dev/null",
  129.         workdir, escape_name(M.real_filename, 0),
  130.         escape_name(M.filename, 1));
  131.     break;
  132.       case COMPRESSED_ARJ:
  133.     guess_arj_filename();
  134.     chdir(TMP_DIR);
  135.     sprintf(buf, ARJ_COMMAND "%s/%s >& /dev/null < /dev/null",
  136.         workdir, escape_name(M.real_filename, 0));
  137.     break;
  138.       default:
  139.     }
  140.  
  141.     /* Uncompress and open file */
  142.     switch(filetype) {
  143.       case COMPRESSED_GZIP:
  144.       case COMPRESSED_LHA:
  145.       case COMPRESSED_ZIP:
  146.       case COMPRESSED_ARJ:
  147.     tmp=my_system(buf);
  148.     sprintf(buf, TMP_DIR "/%s", M.filename);
  149.     if(tmp) {
  150.         unlink(buf);
  151.         if(tmp > 0) {
  152.         print_status("Error uncompressing");
  153.         sleep(1);
  154.         }
  155.         return 0;
  156.     }
  157.     
  158.     /* Open uncompressed module */
  159.     if((fd=open(buf, O_RDONLY, 0)) == -1) {
  160.         info("Unable to open file '%s'.\n", buf);
  161.         return 0;
  162.     }
  163.     break;
  164.       default: /* Assume non-compressed module */
  165.     if((fd=open(M.real_filename, O_RDONLY, 0)) == -1) {
  166.         print_status("File does not exist");
  167.         info("Unable to open file '%s'.\n", M.real_filename);
  168.         sleep(1);
  169.         return 0;
  170.     }
  171.     }
  172.  
  173.     /* Here and forward buf should contain the name of the temp-file */
  174.     chmod(buf, 0777); /* a+rwx */
  175.     
  176.     /* Try to determine module-format from the filename if needed */
  177.     if(!opt.format) {
  178.     if(strlen(M.filename) > 4) {
  179.         if(is_modtype("mod") || is_modtype("nst"))
  180.         opt.format=MODFORMAT_MOD;
  181.         else if(is_modtype("ult"))
  182.         opt.format=MODFORMAT_ULT;
  183.         else if(is_modtype("mtm"))
  184.         opt.format=MODFORMAT_MTM;
  185.         else if(is_modtype("s3m"))
  186.         opt.format=MODFORMAT_S3M;
  187.     }
  188.     if(!opt.format)
  189.         opt.format=MODFORMAT_MOD; /* Default to MOD-format */
  190.     }
  191.     
  192.     M.format=opt.format;
  193.     M.sample=0;
  194.     
  195.     switch(opt.format) {
  196.       case MODFORMAT_MOD:
  197.     tmp=load_mod(fd); /* MOD */
  198.     break;
  199.       case MODFORMAT_ULT:
  200.     tmp=load_ult(fd); /* ULT */
  201.     break;
  202.       case MODFORMAT_MTM:
  203.     tmp=load_mtm(fd); /* MTM */
  204.     break;
  205.       case MODFORMAT_S3M:
  206.     tmp=load_s3m(fd); /* S3M */
  207.     break;
  208.       default:
  209.     error("Error selecting format.\n");
  210.     }
  211.     close(fd);
  212.     
  213.     if(M.nr_samples && M.sample)
  214.     M.sample[0].valid=0;  /* Make sure sample 0 is invalid */
  215.     
  216.     if(filetype) { /* Remove temp-file if module was compressed */
  217.     unlink(buf);
  218.     }
  219.  
  220.     info("\nTracks stored: %d/%d.\n", M.nr_tracks, M.nr_voices*M.nr_patterns);
  221.  
  222.     return tmp;      /* Return status from load_xxx */
  223. }
  224.  
  225.  
  226. int is_modtype(char *type)
  227. {
  228.     char buf[5], name[256];
  229.     int i;
  230.     
  231.     strcpy(name, M.filename);
  232.     for(i=0; name[i]; ++i)
  233.     if(isalpha(name[i]) && isupper(name[i]))
  234.         name[i]=tolower(name[i]);
  235.  
  236.     i=strlen(name)-4;
  237.     
  238.     buf[0]='.';
  239.     strcpy(buf+1, type);
  240.     if(!strncmp(name+i, buf, 4))        /* .xxx */
  241.     return 1;
  242.     buf[0]='_';
  243.     if(!strncmp(name+i, buf, 4))        /* _xxx */
  244.     return 1;
  245.  
  246.     strcpy(buf, type);
  247.     strcat(buf, ".");
  248.     if(!strncmp(name, buf, 4))          /* xxx. */
  249.     return 1;
  250.     buf[3]='_';
  251.     if(!strncmp(name, buf, 4))          /* xxx_ */
  252.     return 1;
  253.     
  254.     return 0;
  255. }
  256.  
  257.  
  258. void guess_lha_filename(void)
  259. {
  260.     char buf[PATH_MAX+1], name[PATH_MAX+1];
  261.     int size;
  262.     FILE *fp;
  263.     
  264.     sprintf(buf, LHA_COMMAND_LIST "%s/%s < /dev/null",
  265.         workdir, M.real_filename);
  266.     if(!(fp=popen(buf, "rb")))
  267.     return;
  268.  
  269.     strcpy(name, M.filename); /* Default to name minus suffix */
  270.     size=0;
  271.     
  272.     /* Find the largest file */
  273.     if(fgets(buf, PATH_MAX, fp) && fgets(buf, PATH_MAX, fp)) {
  274.     while(!feof(fp)) {
  275.         if(!fgets(buf, PATH_MAX, fp))
  276.         break;
  277.         if(strlen(buf) <= 1 || *buf == '-')
  278.         break;
  279.         
  280.         buf[strlen(buf)-1]=0; /* Remove lf */
  281.         if(atoi(&buf[18]) > size) {
  282.         size=atoi(&buf[18]);
  283.         strcpy(name, &buf[46]);
  284.         }
  285.     }
  286.     }
  287.     pclose(fp);
  288.     strcpy(M.filename, name);
  289. }
  290.  
  291.  
  292. void guess_zip_filename(void)
  293. {
  294.     char buf[PATH_MAX+1], name[PATH_MAX+1];
  295.     int size;
  296.     FILE *fp;
  297.     
  298.     sprintf(buf, ZIP_COMMAND_LIST "%s/%s 2> /dev/null < /dev/null",
  299.         workdir, M.real_filename);
  300.     if(!(fp=popen(buf, "rb")))
  301.     return;
  302.     
  303.     strcpy(name, M.filename); /* Default to name minus suffix */
  304.     size=0;
  305.     
  306.     /* Find the largest file */
  307.     if(fgets(buf, PATH_MAX, fp) && fgets(buf, PATH_MAX, fp)) {
  308.     while(!feof(fp)) {
  309.         if(!fgets(buf, PATH_MAX, fp))
  310.         break;
  311.         if(strlen(buf) <= 3 || !strncmp(buf, " -", 2))
  312.         break;
  313.         
  314.         buf[strlen(buf)-1]=0; /* Remove lf */
  315.         if(atoi(&buf[0]) > size) {
  316.         size=atoi(&buf[0]);
  317.         strcpy(name, &buf[27]);
  318.         }
  319.     }
  320.     }
  321.     pclose(fp);
  322.     strcpy(M.filename, name);
  323. }
  324.  
  325.  
  326. void guess_arj_filename(void)
  327. {
  328.     char buf[PATH_MAX+1], name[PATH_MAX+1];
  329.     int size, i;
  330.     FILE *fp;
  331.     
  332.     sprintf(buf, ARJ_COMMAND_LIST "%s/%s 2> /dev/null < /dev/null",
  333.         workdir, M.real_filename);
  334.     if(!(fp=popen(buf, "rb")))
  335.     return;
  336.     
  337.     strcpy(name, M.filename); /* Default to name minus suffix */
  338.     size=0;
  339.     /* Find the largest file */
  340.     if(fgets(buf, PATH_MAX, fp) && fgets(buf, PATH_MAX, fp) &&
  341.        fgets(buf, PATH_MAX, fp) && fgets(buf, PATH_MAX, fp) &&
  342.        fgets(buf, PATH_MAX, fp) && fgets(buf, PATH_MAX, fp)) {
  343.     while(!feof(fp)) {
  344.         if(!fgets(buf, PATH_MAX, fp))
  345.         break;
  346.         if(strlen(buf) <= 14 || !strncmp(buf, "------------ -", 14))
  347.         break;
  348.         
  349.         buf[strlen(buf)-1]=0; /* Remove lf */
  350.         if(atoi(&buf[13]) > size) {
  351.         size=atoi(&buf[13]);
  352.         
  353.         /* Fix filename, dos-way (8.3) + lowercase for unix unarj */
  354.         strncpy(name, &buf[0], 12);
  355.         for(i=11; i >= 0 && name[i] == ' '; --i)
  356.             ;
  357.         name[++i]=0;
  358.         for(i=0; name[i]; ++i)
  359.             if(isalpha(name[i]) && isupper(name[i]))
  360.             name[i]=tolower(name[i]);
  361.         }
  362.     }
  363.     }
  364.     pclose(fp);
  365.     strcpy(M.filename, name);
  366. }
  367.  
  368.  
  369. void print_used_effects(void)
  370. {
  371.     int v, l;
  372.  
  373.     if(!opt.verbose)
  374.     return;
  375.  
  376.     printf("\nEFX: ");
  377.     l=0;
  378.     for(v=0; v < NR_EFX; ++v)
  379.     if(effect_used[v]) {
  380.         printf("%s ",effectnames[v]);
  381.         ++l;
  382.     }
  383.     printf("\n(# of EFX: %d)\n",l);
  384. }
  385.  
  386.  
  387. /* Returns the note corresponding to the supplied period. Not the closest,
  388.  * but the same that PT finds.
  389.  */
  390.  
  391. unsigned char period2note(unsigned int period)
  392. {
  393.     int i;
  394.  
  395.     if(period > periodtable[0]) {
  396.     info("Forced to take C-0. PerDiff: %d ", period-periodtable[0]);
  397.     return BASE_NOTE;
  398.     }
  399.     
  400.     if(period < periodtable[NR_OCTAVES*12-1]) {
  401.     info("Forced to take B-9. PerDiff: %d ",
  402.          period-periodtable[NR_OCTAVES*12-1]);
  403.     return BASE_NOTE+NR_OCTAVES*12-1;
  404.     }
  405.     
  406.     for(i=0; i < NR_OCTAVES*12; ++i)
  407.     if(period >= periodtable[i])
  408.         return BASE_NOTE+i;
  409.     
  410.     assert(0); /* never reached */
  411.     return 0;  /* removes warning */
  412. }
  413.  
  414.  
  415. void free_module(void)
  416. {
  417.     int i;
  418.     
  419.     for(i=0; i < MAX_VOICES; ++i)
  420.     if(M.track_idx[i])
  421.         free(M.track_idx[i]);
  422.     
  423.     if(M.tracks) {
  424.     for(i=0; i < M.nr_tracks; ++i)
  425.         free(M.tracks[i]);
  426.     free(M.tracks);
  427.     }
  428.     
  429.     if(opt.format == MODFORMAT_ULT && M.songtext)
  430.     free(M.songtext);
  431.     
  432.     if(M.sample)
  433.     free(M.sample);
  434.     
  435.     zero_resources();
  436. }
  437.  
  438.  
  439. void zero_resources(void)
  440. {
  441.     int v;
  442.     
  443.     for(v=0; v < MAX_VOICES; ++v)
  444.     M.track_idx[v]=0;
  445.     
  446.     M.tracks=0;
  447.     M.sample=0;
  448.     M.songtext=0;
  449. }
  450.